'''
数据清洗和相关性分析操作
'''
import pandas as pd
import  numpy as np
import  re
import warnings
import matplotlib.pyplot as plt
warnings.filterwarnings('ignore')

# 读取CSV文件
house_data = pd.read_csv("Buildings_finall.csv")

# 将数据转换为DataFrame
pd.DataFrame(house_data)

# 数据预览
print(house_data.shape)  # 打印数据的维度
print(house_data.info())  # 打印数据的基本信息，包括列名、数据类型和非空值数量
print(house_data.describe())  # 打印数值型列的统计信息，如均值、标准差、最小值、最大值等

# 初始化一个字典，用于存储每列的缺失值个数
missing = {}

# 遍历DataFrame的每一列
for column in house_data.columns:
    # 计算当前列的缺失值个数
    missing_count = house_data[column].isnull().sum()
    # 将计算结果存入字典
    missing[column] = {'missing': missing_count}

# 打印各列的缺失值个数
for column, info in missing.items():
    print(f"列名: {column}, 缺失值个数: {info['missing']}")


# 选项类异常值处理
house_data['建筑年代'] = house_data['建筑年代'].str.replace('年', '')  # 去除“年”字
house_data['建筑年代'] = pd.to_datetime(house_data['建筑年代'], errors='coerce')  # 将建筑年代转换为日期类型
house_data['建筑年代'] = house_data['建筑年代'].dt.year  # 提取年份

# 对“电梯”列进行异常值处理
house_data['电梯'] = house_data['电梯'].str.strip()  # 去除字符串两端的空格
lift = ['有', '无']  # 定义有效的电梯选项
house_data.loc[~house_data['电梯'].isin(lift), '电梯'] = np.nan  # 将不在有效选项内的值设为NaN

# 对“产权性质”列进行异常值处理
Nature_of_property_rights = ['个人产权']  # 定义有效的产权性质选项
house_data.loc[~house_data['产权性质'].isin(Nature_of_property_rights), '产权性质'] = np.nan

# 对“装修”列进行异常值处理
fitment = ['毛坯', '精装修', '简装修']  # 定义有效的装修选项
house_data.loc[~house_data['装修'].isin(fitment), '装修'] = np.nan

# 对“建筑结构”列进行异常值处理
house_data['建筑结构'] = house_data['建筑结构'].str.strip()
Building_Structure = ['平层']  # 定义有效的建筑结构选项
house_data.loc[~house_data['建筑结构'].isin(Building_Structure), '建筑结构'] = np.nan

# 对“建筑类别”列进行异常值处理
house_data['建筑类别'] = house_data['建筑类别'].str.strip()
Building_Category = ['板楼']  # 定义有效的建筑类别选项
house_data.loc[~house_data['建筑类别'].isin(Building_Category), '建筑类别'] = np.nan

# 对“住宅类别”列进行异常值处理
house_data['住宅类别'] = house_data['住宅类别'].str.strip()
Building_Structure = ['普通住宅']  # 定义有效的住宅类别选项
house_data.loc[~house_data['住宅类别'].isin(Building_Structure), '住宅类别'] = np.nan

# 初始化一个字典，用于存储每列的缺失值个数
missing = {}

# 遍历DataFrame的每一列
for column in house_data.columns:
    # 计算当前列的缺失值个数
    missing_count = house_data[column].isnull().sum()
    # 将计算结果存入字典
    missing[column] = {'missing': missing_count}

# 打印各列的缺失值个数
for column, info in missing.items():
    print(f"列名: {column}, 缺失值个数: {info['missing']}")

#注：
#对于缺失值的处理，在画图时对单个列进行处理避免对整体数据的影响
#对于重复值的处理，在画图时对相应列进行分组聚合处理避免对整体数据的影响

# 处理单位
data_digit = ['面积', '单价(元/m²)']
for column in data_digit:
    house_data[column] = house_data[column].apply(lambda x: re.sub(r'[^\d.-]', '', x))  # 去除非数字和非小数点字符

# 打印唯一标签值
for column in ['区域', '建筑年代', '电梯', '布局', '产权性质', '面积', '层数', '住宅类别', '建筑结构', '建筑类别',
               '朝向', '楼层', '装修', '单价(元/m²)', '总价（万元）']:
    print(house_data[column].unique())  # 打印每列的唯一值

# 再次打印数据的维度、基本信息和统计信息
print(house_data.shape)
print(house_data.info())
print(house_data.describe())

# 打印处理后的缺失值个数
for column, info in missing.items():
    print(f"列名: {column}, 缺失值个数: {info['missing']}")

# 打印处理后的数据
print(house_data)

# 将处理后的数据保存到CSV文件
house_data.to_csv("Buildings_finall_handle.csv", encoding='utf_8_sig', index=False)

'''
对相关性进行探索性分析
'''
from pylab import mpl
mpl.rcParams["axes.unicode_minus"] = False
mpl.rcParams['font.family'] = 'Microsoft YaHei'
from sklearn.preprocessing import MinMaxScaler
import seaborn as sns

# 读取CSV文件
df = pd.read_csv("Buildings_finall_handle.csv")

# 打印“区域”列中的唯一值
print(df['区域'].unique())

# 去除“区域”列中字符串的首尾空格
df['区域'] = df['区域'].str.strip()

# 定义一个替换字典，用于将“区域”列中的特定值替换为其他值
replace_dict = {
    '瑞辰玖阙': '兰州新区',
    '永登': '永登县',
    '瑞辰金悦府': '兰州新区',
    '海亮·公园学府': '兰州新区',
    '皋兰': '皋兰县',
    '新区万科城': '兰州新区',
    '远达锦绣半岛': '安宁区',
    '安宁': '安宁区',
    '安宁庭院': '安宁区',
    '酒泉御园飞天花苑住宅小区': '安宁区',
    '新厦水岸天成': '安宁区',
    '兰石豪布斯卡璟园': '七里河区',
    '七里河': '七里河区',
    '中和教育世家': '安宁区',
    '天泰世纪嘉园': '七里河区',
    '百合家园': '七里河区',
    '兰州恒大帝景': '七里河区'
}

# 使用replace方法替换“区域”列中的值
df['区域'] = df['区域'].replace(replace_dict)

# 打印替换后的“区域”列
print(df['区域'])

# 计算每个区域的平均总价
df.groupby("区域")['总价（万元）'].mean()

# 使用pivot_table方法创建透视表，计算每个区域和楼层的平均总价
df_ana = pd.pivot_table(df, values=['总价（万元）'], index=['区域', '楼层'], aggfunc='mean')
print(df_ana)

# 创建一个新列“经济发展水平”，并将其设置为与“区域”列相同的值
df['经济发展水平'] = df['区域']
#欲探索经济发展对房价的影响因素，通过了解2023年兰州各区收入水平，对地区进行数据替换
# 定义一个替换字典，用于将“经济发展水平”列中的特定值替换为数值

df['经济发展水平'] = df['区域']
replace_dict = {
    '兰州新区':374.3,
     '永登县':144.4,
     '皋兰县':67.3,
     '安宁区':305.81,
     '七里河区':610.87,
}

# 使用replace方法替换“经济发展水平”列中的值
df['经济发展水平'] = df['经济发展水平'].replace(replace_dict)
print(df['经济发展水平'])

# 定义要归一化的列
columns_to_normalize = ['经济发展水平', '面积', '单价(元/m²)', '总价（万元）', '层数']

# 创建一个MinMaxScaler对象
scaler = MinMaxScaler()

# 对指定的列进行归一化处理
df[columns_to_normalize] = scaler.fit_transform(df[columns_to_normalize])

# 提取归一化后的列，创建一个新的DataFrame
df_normalize = df[columns_to_normalize]

# 计算归一化后列的相关系数矩阵，并打印
print(df_normalize.corr())

# 定义要计算相关系数的列
selected_columns = ['经济发展水平', '面积', '单价(元/m²)', '总价（万元）', '层数']

# 计算选定列的相关系数矩阵
corr_matrix = df[selected_columns].corr()

# 打印相关系数矩阵
print(corr_matrix)

# 绘制热图，显示选定列的相关系数
plt.figure(figsize=(8, 6))

sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')

plt.title('选定列的相关系数热图')

plt.savefig('chart.png')  # 保存热图为PNG文件

plt.show()  # 显示热图
